import json
import datetime
import string
import random

from PIL import Image
from django.utils import timezone
from django.db import models
from django.conf import settings

from apps.system.SendSms import SMS
from utils.exception import CustomError
from utils.uploadfile import SaveTempFile, TenCenCos


class VCode(models.Model):
    """验证码"""
    SIGN = 1
    FORGET_PASSWORD = 2
    TYPE_CHOICES = (
        (SIGN, '注册'),
        (FORGET_PASSWORD, '忘记密码')
    )

    SUCCESSED = 1
    FAILED = 0
    STATUS_CHOICES = (
        (SUCCESSED, '发送成功'),
        (FAILED, '发生失败')
    )

    vcode = models.CharField(max_length=6, verbose_name='验证码')
    mobile = models.CharField(verbose_name='手机号', max_length=11)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    type = models.PositiveSmallIntegerField(verbose_name='用途', choices=TYPE_CHOICES, editable=False, default=SIGN)
    status = models.PositiveSmallIntegerField(verbose_name='状态', choices=STATUS_CHOICES, editable=False,
                                              default=SUCCESSED)
    error = models.CharField(verbose_name='错误原因', max_length=200, null=True)
    is_used = models.BooleanField(verbose_name='是否已经验证过', default=False)

    @staticmethod
    def verify(mobile, code, type):
        if mobile is None and code is None:
            raise CustomError("参数无效！")

        if type not in [VCode.SIGN, VCode.FORGET_PASSWORD]:
            raise CustomError("参数无效！")

        vc = VCode.objects.filter(mobile=mobile, type=type, status=VCode.SUCCESSED, is_used=False).order_by(
            '-id').first()
        if not vc or vc.vcode != code:
            raise CustomError("验证码错误")

        if (timezone.now() - vc.create_time).seconds < 5 * 60:
            vc.is_used = True
            vc.save()
        return

    @staticmethod
    def send(mobile, type):
        if mobile == '' or not mobile:
            raise CustomError('手机号参数参数无效')
        # if type == VCode.SIGN:
        #     template_id = settings.SMS_TENCENT_TEMPLATE['SIGN']
        # elif type == VCode.FORGET_PASSWORD:
        #     template_id = settings.SMS_TENCENT_TEMPLATE['FORGET_PASSWORD']
        # else:
        #     raise CustomError('验证码类型参数无效')

        vcs = VCode.objects.filter(mobile=mobile, type=type).order_by('-id')
        if vcs.count() > 0:
            vc = vcs[0]
            if (timezone.now() - vc.create_time).seconds < 60:
                raise CustomError('获取太频繁，请稍后再试！')
        vcode = ''.join(random.sample(string.digits, 6))

        sms = SMS()
        resp = sms.send('+86%s' % mobile, vcode)
        if resp['Code'] == 'Ok':
            VCode.objects.create(mobile=mobile, vcode=vcode, type=type)
            return '发送成功'

        else:
            VCode.objects.create(mobile=mobile, vcode=vcode, type=type, status=VCode.FAILED,
                                 error=resp['Message'])
            return '发送失败'

    class Meta:
        db_table = 'system_code'
        verbose_name = '短息验证码'
        ordering = ['-create_time']


# class LogManager(models.Manager):
#     def addLog(self, user, type, description, data=None):
#         def default(o):
#             if isinstance(o, datetime.datetime):
#                 return strftime(o)
#             elif isinstance(o, datetime.date):
#                 return strfdate(o)
#
#         log = self.model(user=user, type=type, description=description)
#         if data:
#             # default  迭代
#             log.data = json.dumps(data, default=default)
#         log.save()
#         return log


# class Log(models.Model):
#     INSERT = 1
#     DELETE = 2
#     UPDATE = 3
#
#     TYPE_CHOICES = (
#         (INSERT, '插入'),
#         (DELETE, '删除'),
#         (UPDATE, '更新')
#     )
#
#     user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='操作人', on_delete=models.PROTECT)
#     type = models.PositiveSmallIntegerField(verbose_name='操作类型', choices=TYPE_CHOICES)
#     description = models.CharField(verbose_name='操作描述', max_length=1000)
#     data = models.TextField(verbose_name='操作数据', null=True)
#     create_time = models.DateTimeField(verbose_name='操作时间', auto_now_add=True, editable=False)
#
#     objects = LogManager()
#
#     class Meta:
#         db_table = 'system_log'
#         verbose_name = '后台系统日志'
#         ordering = ['-create_time']
#         index_together = ('create_time',)
class UploadManager(models.Manager):
    def upload(self, file, type='others'):
        # 文件名
        file_name = '%s-%s.%s' % (type, timezone.now().strftime('%Y%m%d%H%M%S%f'), file.name.split('.')[-1])
        width = None
        height = None
        # 1.保存到本地
        file_name = file_name.lower()
        loacl_file_path = SaveTempFile(file, file_name)

        # 2.剪切图片
        # try:
        #     img = Image.open(file_path)
        #     x, y = img.size
        #     if x > 1440:
        #         img = img.resie((1440, int((y / x) * 1440)), Image.ANTIALIAS)
        #         img.save(file_path)
        #     width, height = img.size
        # except:
        #     pass

        # 3.图片保存到腾讯云
        tencen_cos = TenCenCos()
        save_path = '%s/%s' % (type, file_name)
        tencen_cos.upload(loacl_file_path, save_path)

        # 4.保存
        # https://qiaofinn1-1300484618.cos.ap-chengdu.myqcloud.com/others/others-20200718170943473462.jpg
        instance = Upload.objects.create(filepath=save_path, type=type,
                                         width=width, height=height)
        return instance


class Upload(models.Model):
    OTHERS = 'others'
    DIARY = 'diary'
    COMMENT = 'comment'
    MEDIA = 'media'
    TYPE_CHOICE = (
        (OTHERS, '其他'),
        (DIARY, '日记'),
        (COMMENT, '评论'),
        (MEDIA, '电影')
    )
    type = models.CharField(choices=TYPE_CHOICE, max_length=50, default=OTHERS, verbose_name='图片类别')
    filepath = models.CharField(verbose_name='路径', max_length=200)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True, editable=False)
    # get_user_model()实际获取的是settings.AUTH_USER_MODEL指定的User model
    # user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='上传者', on_delete=models.PROTECT)
    width = models.IntegerField(verbose_name='图片宽度', null=True)
    height = models.IntegerField(verbose_name='图片长度', null=True)

    objects = UploadManager()

    class Meta:
        db_table = 'system_upload'
        verbose_name = '图片'

    def __str__(self):
        return self.filepath
